package org.coderjonny.repository;

import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.bouncycastle.cert.ocsp.Req;
import org.coderjonny.bean.Product;
import org.coderjonny.bean.User;
import org.coderjonny.constant.HttpCode;
import org.coderjonny.dto.Request;
import org.coderjonny.dto.Result;
import org.coderjonny.dto.order.OrderParam;
import org.coderjonny.dto.product.ProductId;
import org.coderjonny.dto.product.UpdateStock;
import org.coderjonny.dto.user.UserId;
import org.coderjonny.exception.BusinessException;
import org.coderjonny.feign.ProductService;
import org.coderjonny.feign.UserService;
import org.coderjonny.trace.TraceIdUtil;
import org.coderjonny.util.DiscoveryUtil;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Repository;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;

@Repository
public class OrderRepository {

    @Resource
    private RestTemplate restTemplate;
    @Resource
    private UserService userService;
    @Resource
    private ProductService productService;
    public User queryUserById(OrderParam orderParam){
        UserId userId = new UserId();
        userId.setUserId(orderParam.getUserId());
        Request<UserId> request = getRequest(userId);
        Result<User> userResult = userService.getByUserId(request);
        if (!userResult.getCode().equals(HttpCode.SUCCESS)){
            throw new BusinessException(userResult.getMsg());
        }
        return userResult.getData();
    }

    public Product queryProductById(OrderParam orderParam){
        ProductId productId = new ProductId();
        productId.setProductId(orderParam.getProductId());
        Request<ProductId> request = getRequest(productId);
        Result<Product> productResult = productService.getByProductId(request);
        if (!productResult.getCode().equals(HttpCode.SUCCESS)){
            throw new BusinessException(productResult.getMsg());
        }
        return productResult.getData();
    }

    public Integer updateStock(OrderParam orderParam){
        UpdateStock updateStock = new UpdateStock();
        updateStock.setProductId(orderParam.getProductId());
        updateStock.setCount(orderParam.getCount());
        Request<UpdateStock> request = getRequest(updateStock);
        Result<String> result = productService.updateStockById(request);
        if (!result.getCode().equals(HttpCode.SUCCESS)){
            throw new BusinessException(result.getMsg());
        }
        return result.getCode();
    }

    @Deprecated
    private <T> HttpEntity<Request<T>> getHttpEntity(T data){
        Request<T> request = new Request<>();
        request.setTraceId(TraceIdUtil.getNowTraceId());
        request.setData(data);
        LinkedMultiValueMap<String, String> headerMap = new LinkedMultiValueMap<String,String>(){
            {
                add(HttpHeaders.CONTENT_TYPE,MediaType.APPLICATION_JSON_VALUE);
            }
        };
        return new HttpEntity<>(request,headerMap);
    }

    private <T> Request<T> getRequest(T data){
        Request<T> request = new Request<>();
        request.setTraceId(TraceIdUtil.getNowTraceId());
        request.setData(data);
        return request;
    }

    @Deprecated
    private <T> Result<T> getResponse(HttpEntity httpEntity,String url,Class<T> responseClazz){
        JavaType javaType = new ObjectMapper().getTypeFactory().constructParametricType(Result.class, responseClazz);
        ParameterizedTypeReference<Result<T>> ptr = ParameterizedTypeReference.forType(javaType);
        ResponseEntity<Result<T>> responseEntity = restTemplate.exchange(url, HttpMethod.POST, httpEntity, ptr);
        if (responseEntity.getBody() == null){
            return null;
        }
        return responseEntity.getBody();
    }


}
